package com.amiba.crm.admin.auth.core.validate.code;

import cn.hutool.core.util.StrUtil;
import com.amiba.crm.admin.auth.core.exception.ValidateCodeException;
import com.amiba.crm.admin.common.constant.CommonConstants;
import com.amiba.crm.admin.common.util.R;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;

/**
 * 验证码拦截器
 * @author HZI.HUI
 * 2019/5/23 18:34
 */
@Slf4j
@AllArgsConstructor
public class ValidateCodeFilter implements Filter {

    private RedisTemplate redisTemplate;
    private ObjectMapper objectMapper;

    @Override
    @SneakyThrows
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        try {
            checkCode(servletRequest);
        } catch (ValidateCodeException e) {
            response.setStatus(HttpStatus.PRECONDITION_REQUIRED.value());
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(objectMapper.writeValueAsString(new R<>(e)));
            return;
        }
        filterChain.doFilter(servletRequest,servletResponse);
    }

    /**
     * 检查code
     * @param request
     */
    @SneakyThrows
    private void checkCode(ServletRequest request) {
        String code = request.getParameter("code");

        if (StrUtil.isBlank(code)) {
            throw new ValidateCodeException("验证码不能为空");
        }

        String randomStr = request.getParameter("randomStr");
        String key = CommonConstants.DEFAULT_CODE_KEY + randomStr;
        if (!redisTemplate.hasKey(key)) {
            throw new ValidateCodeException("验证码不合法");
        }

        Object codeObj = redisTemplate.opsForValue().get(key);

        if (codeObj == null) {
            throw new ValidateCodeException("验证码不合法");
        }

        String saveCode = codeObj.toString();
        if (StrUtil.isBlank(saveCode)) {
            redisTemplate.delete(key);
            throw new ValidateCodeException("验证码不合法");
        }

        if (!StrUtil.equals(saveCode, code)) {
            redisTemplate.delete(key);
            throw new ValidateCodeException("验证码不合法");
        }

        redisTemplate.delete(key);
    }

    @Override
    public void init(FilterConfig filterConfig) {}

    @Override
    public void destroy() {

    }
}
